package com.example.adminframework.constant;

import com.fasterxml.jackson.annotation.JsonFormat;

import java.util.List;

/**
 * 错误码
 * <p>
 * <p>
 * 其中应用程序错误码分为三大类
 * 1、请求错误 包括请求参数类错误 验证码、表单参数等
 * 2、网络错误 与中间件, 第三方服务连通时的网络错误(redis mysql es)
 * 3、响应错误 程序异常报错或BUG
 */
//json序列化枚举
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum ErrorCode {
    /**
     * 1、请求错误 包括请求参数类错误 验证码、表单参数等
     */
    // token不存在
    TOKEN_NULL(10001, "token is null"),
    // token解析格式错误
    TOKEN_FORMAT(10002, "token format error"),
    // token内容错误
    TOKEN_CONTENT(10003, "token content error"),
    // token内容前后不一致 确认被修改过
    TOKEN_MODIFIED(10004, "token is modified"),
    // token过期
    TOKEN_EXPIRE(10005, "token expire"),
    // 用户名密码错误
    LOGIN_PARAM_NULL(11000, "name or password is null"),
    // 用户被锁定
    LOGIN_USER_LOCKED(11002, "user is locked"),
    // 权限未经许可
    PERMISSION_UNAUTHORIZED(10007, "permission unauthorized"),
    // 权限有关联
    PERMISSION_ARE_ASSOCIATED(10009, "Permissions are associated"),
    // 参数非法
    NON_PARAMETRIC(10008, "non_parametric"),
    // 资源未找到
    CONTENT_NOT_FOUND(19000, "content not found"),
    // 未标注整理的应用程序错误
    UN_KNOWN_ERROR(99999, "Internal server error"),
    // 请求参数为null
    PARAMETER_IS_NULL(11003, "parameter is null"),
    //验证码为空或错误
    CAPTCHA_ERROR(10006, "captcha is null or error"),
    //url有问题
    URL_ERROR(10010, "url is bad or error"),
    //计划策略错误
    MISFIRE_ERROR(10011, "计划策略错误"),
    //定时调度创建错误
    SCHEDULER_ERROR(10012, "定时调度创建错误"),
    STOP_ERROR(10090, "转换停止错误"),
    NOT_TRANS_ERROR(10091, "没有这个转换"),
    XML_ERROR(10092, "xml格式有误"),
    PLEASE_DELETE_ALL_REPORT(10105,"存在报表关联，请清除后再删除"),

    FILE_READ_ERROR(10093, "读取文件出错"),
    SCRIPT_ID_REPEATED(10094, "脚本ID已存在,请勿重复"),

    PARAMETER_REPEATED(10094, "参数在数据库已存在,请勿重复"),
    UPDATE_NOT_ALLOWED(10095, "不允许修改"),
    DELETE_NOT_ALLOWED(10096, "不允许删除"),
    IS_CONFIRM_DELETE(10097, "存在关联关系,是否确认继续删除?"),
    IS_CONFIRM_WIDGET_DELETE(10097, "存在关联组件,是否联动删除?"),
    BUILT_IN_UPDATE_NOT_ALLOWED(10098, "内置数据不允许修改"),
    BUILT_IN_DELETE_NOT_ALLOWED(10099, "内置数据不允许删除"),
    LABEL_MUST_BE_SELECTED(10100, "请选择标签"),
    DATA_NOT_ALLOW_REPEAT(10101, "数据重复"),
    WORKFLOW_APPROVE_UNAUTHORIZED(10102, "未经授权的工作流审批"),
    FILE_TYPE_NOT_ALLOWED(10103, "文件类型不合法"),
    GROUP_ID_MUST_CHOOSE(10104, "请选择资产组"),
    PLACE_DELETE_ALL_ASSET(10105, "存在资产关联，请清除后再删除"),
    DELETE_FAIL(10096, "删除失败"),
    UPDATE_FAIL(10095, "更新失败"),
    OPERATOR_FAIL(10095, "操作失败"),
    PLEASE_DELETE_ALL_DASHBOARD(10105, "存在仪表板关联，请清除后再删除"),
    ETL_XML_ERROR(10106, "etl数据有误"),
    ETL_RUN_ERROR(10107, "etl运行错误"),
    ETL_API_FORBID(10108, "接口key验证失败"),
    WORKFLOW_START_ERROR(10109, "工作流启动异常,请检查相关配置信息"),
    WORKFLOW_NO_OUTGOING(10110, "工作流启动异常, 表达式判断没有可选路径"),
    WORKFLOW_NO_PARAM(10111, "工作流启动异常, 表达式判断变量没有赋值"),
    SCENE_FILTER_ERROR(10112, "此告警过滤已关联场景,不能修改状态"),
    SCENE_COMPRESS_ERROR(10113, "此告警压缩已关联场景,不能修改状态"),
    SCENE_RELEVANCE_ERROR(11001, "已关联场景,不能删除或者禁用"),
    TASK_SCHEDULE_RELEVANCE_ERROR(11002, "已关联定时调度,不能删除或者禁用"),
    TASK_SCHEDULE_RELEVANCE_UPDATE_ERROR(11003, "已关联定时调度,不能保存为草稿,必须保存并发布"),
    ETL_RELEVANCE_ERROR(11004, "已关联数据抽取转换,不能删除"),
    SHARE_CANCEL(12001, "分享已失效"),
    SHARE_DELETE(12001, "分享不存在"),
    SHARE_TIMEOUT(12001, "分享已超时"),
    SHARE_EXIST(12001, "分享在有效期内"),
    ANALYSIS_RELEVANCE_ERROR(11004, "该研判已关联其他研判,不能保存为草稿、删除或者禁用"),
    ANALYSIS_SCRIPT_RELEVANCE_ERROR(11005, "code为空"),
    ANALYSIS_SCENE_RELEVANCE_ERROR(11006, "的研判已被其他场景关联,不能保存为草稿、删除或者禁用"),
    ANALYSIS_RELATION_LOOP_ERROR(11007, "研判-子研判存在循环引用关系，请检查当前子研判！"),
    ROLE_RELATION_USER_ERROR(11008, "已关联用户，不能删除"),
    TABLE_NAME_NOT_FOUND(13001, "未找到该数据表名!"),
    ANALYSIS_NAME_REPEATED(14001, "告警研判名称重复"),
    ANALYSIS_INCIDENT_NOT_FOUND(14002,"未找到告警信息!"),

    MODEL_FILE_ANALYSIS_ERROR(15000, "数据文件解析错误"),
    MODEL_FILE_DATA_COLUMN_ERROR(15001, "数据模型-文件,上传的文件至少要有字段数据"),
    SQL_UNSAFE_ERROR(15002, "当前系统仅支持查询操作, 请输入查询操作SQL语句"),
    MODEL_FILE_DATA_COLUMN_TYPE_ERROR(15003, "字段类型不适配!"),
    MODEL_FILE_DATA_PROCESS_ERROR(15004, "内存数据处理出错"),
    MODEL_FILE_OPERATOR_ERROR(15005, "操作符非法"),
    MODEL_FILE_EMPTY_ERROR(15006,"数据模型-文件处理后的数据为空!"),
    MODEL_FILE_HEADER_REPETITION(15007,"数据模型-表头重复"),
    MODEL_FILE_CHINESE_FIELD_ERROR(15008,"字段名不能含有中文! 请检查上传文件的第一行数据!"),
    MODEL_FILE_TYPE_ERROR(15009,"文件类型不匹配!"),
    MEMORY_PROCESS_TYPE_ERROR(16001,"内存数据处理类型错误"),
    MEMORY_PROCESS_GROUP_ERROR(16002,"内存数据处理分组出错"),
    MEMORY_PROCESS_SELECT_GROUP_ERROR(16003,"内存数据处理查询的字段不在分组字段中!"),
    TEMPORARY(99998, "临时"),
    AUTH_ERROR(15007, "授权校验为通过"),

    /**
     * 2、网络错误 与中间件, 第三方服务连通时的网络错误
     */
    ELASTICSEARCH_DEFAULT_KEY_ERROR(20001, "elasticsearch key 'defaultKey' is invalid"),
    ELASTICSEARCH_QUERY_ERROR(20001, "elasticsearch 查询报错"),
    DATASOURCE_DRIVER_NOT_FOUND(20002, "driver class not found"),
    DATASOURCE_ERROR(20003, "new datasource instance error"),
    RESPONSE_TYPE_ERROR(20004, "返回参数类型错误"),
    LONG_CONNECTION_ERROR(20005, "不支持长连接"),
    FILE_DOWNLOAD_ERROR(20006, "不支持下载"),
    REQUEST_METHOD_ERROR(20007, "请求方式错误"),
    CONNECTION_TIMEOUT(20008, "请求超时"),
    HTTPS_ERROR(20009, "请求协议错误"),
    CONNECTION_ERROR(20010, "请求响应错误"),
    UNKNOWN_HOST_ERROR(20011, "无此连接,请检查url地址是否正确"),
    REQUEST_TYPE_ERROR(20012, "请求参数类型有误"),
    RESPONSE_IMAGE_ERROR(20013, "不支持图片类型"),
    REQUEST_HEADER_ERROR(20014, "请求头有误"),
    THIRD_PARTY_SYSTEM_ERROR(20015, "目标服务器错误"),
    JDBC_PARAM_ERROR(20016, "数据库连接参数有误"),
    JDBC_QUERY_ERROR(20017, "数据库查询报错"),
    JDBC_UPDATE_DML_ERROR(20018, "数据库修改字段报错"),
    JDBC_CREATE_ERROR(20019, "新增表报错"),
    JDBC_DROP_ERROR(20020, "删除表报错"),
    JDBC_ADD_ERROR(20021, "新增数据报错"),
    JDBC_DELETE_ERROR(20022, "删除数据报错"),
    FILE_INPUT_ERROR(20023, "文件导入报错"),
    FILE_EXPORT_ERROR(20024, "文件导出报错"),
    FILE_EXPORT_NOT_ALLOWED_ERROR(20025, "该文件不允许导出!"),
    FILE_EXPORT_NAME_EMPTY(20026, "未指定数据表名称!"),
    IO_STREAM_ERROR(20025, "IO流错误"),
    JDBC_QUERY_TIMEOUT(20027, "数据库查询超时"),
    JDBC_QUERY_TABLE_UN_EXIST(20028, "当前查询数据库表不存在"),
    SQL_ERROR_ERROR(20029, "当前输入的字段名称与数据库冲突, 请重新尝试"),

    /**
     * 3、响应错误 程序异常报错或BUG
     */
    JSON_PARSE_ERROR(30001, "JSON解析错误"),

    SCRIPT_EXECUTE_ERROR(30002, "脚本运行出错"),
    SCRIPT_FORMAT_ERROR(30003, "脚本格式错误"),

    SCRIPT_INIT_ERROR(30004, "脚本初始化错误"),
    IO_ERROR(30005, "IO流出现错误"),

    TYPE_CONVERSION_ERROR(30006, "类型转换错误");
    /**
     * 错误code
     */
    private Integer errorCode;

    /**
     * 错误消息
     */
//    @JsonIgnore
    private String errorMessage;

    ErrorCode() {
    }

    ErrorCode(ErrorCode errorCode) {
        this.errorCode = errorCode.errorCode;
        this.errorMessage = errorCode.errorMessage;
    }

    ErrorCode(Integer code, String message) {
        this.errorCode = code;
        this.errorMessage = message;
    }

    public Integer getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(Integer errorCode) {
        this.errorCode = errorCode;
    }

    public String getErrorMessage() {
        return errorMessage;
    }

    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }

    /**
     * 相关性
     *
     * @param errorCode 错误代码
     * @param names     的名字
     * @return {@link ErrorCode}
     */
    public static ErrorCode isRelevance(ErrorCode errorCode, List<String> names) {
        ErrorCode.TEMPORARY.setErrorCode(0);
        ErrorCode.TEMPORARY.setErrorMessage("");
        StringBuilder message = new StringBuilder("名称为:");
        for (String name : names) {
            message.append(name).append(",");
        }
        ErrorCode.TEMPORARY.setErrorCode(errorCode.errorCode);
        ErrorCode.TEMPORARY.setErrorMessage(message.toString() + errorCode.getErrorMessage());
        return ErrorCode.TEMPORARY;
    }


    /**
     * 动态ErrorCode 使用ErrorCode.TEMPORARY这个枚举成员
     * @param msg 用{}作为占位符
     * @param objs
     * @return
     */
    public static ErrorCode dynamicErrorCode( String msg, Object... objs) {
        for (Object obj : objs) {
            msg = msg.replaceFirst("\\{\\}", String.valueOf(obj));
        }
        ErrorCode.TEMPORARY.setErrorMessage(msg);
        return ErrorCode.TEMPORARY;
    }


    @Override
    public String toString() {
        return "ErrorCode{" +
                "errorCode=" + errorCode +
                ", errorMessage='" + errorMessage + '\'' +
                '}';
    }
}
